﻿/**
 * @file NisCommon_Struct.h
 * @brief NisCommon
 * @details 
 * @mainpage http://www.navinfo.com/
 * @author Navinfo
 * @email 400-810-0880
 * @license Navinfo Co.,Ltd. All rights reserved
 */
#ifndef	__NISCOMMONSTRUCT_H_
#define	__NISCOMMONSTRUCT_H_

PRAGMA_PACK_PUSH

namespace Navinfo {
namespace Nis {

class CMeshId;
class CNodeId;
class CLinkId;
class CDirLinkId;
class CLinkGeoId;
class CDirLinkGeoId;
class CLaneGroupId;
class CLaneId;
class CLaneBoundaryId;
class CObjectShortId;
class CObjectId;
class CObjectGroupShortId;
class CObjectGroupId;
class CObstacleShortId;
class CObstacleId;
class CIntersectionAreaId;
class CLinkCommonAttribute;

/**
 * @brief Link的方向，相对于其数字化方向
 * 
 */
enum LINK_DIRECTION {
	DIR_NEGTIVE = 0,	///<	负方向，与数字化方向相反
	DIR_POSITIVE = 1,	///<	正方向，与数字化方向相同
	DIR_BOTH = 2,	///<	双向
};
/**
 * @brief TRAVEL_DIRECTION
 * 
 */
enum TRAVEL_DIRECTION {
	TRAVEL_DIRECTION_NONE = 0,	///<	不可通行
	TRAVEL_DIRECTION_POSITIVE = 1,	///<	正方向
	TRAVEL_DIRECTION_NEGATIVE = 2,	///<	负方向
	TRAVEL_DIRECTION_BOTH = 3,	///<	双向
};
/**
 * @brief LINK_TYPE
 * 
 */
enum LINK_TYPE {
	NO_SPECIAL = 0x0,	///<	普通道路
	RAMP = 0x1,	///<	匝道，连接两条不同坡度的道路或入口和出口的道路
	ROUNDABOUT = 0x2,	///<	环岛，位于环形交叉口的闭合环路内
};
/**
 * @brief OBJECT_TYPE
 * 
 */
enum OBJECT_TYPE {
	OBJECT_ALL = 0x0000,	///<	全部Object
	OBJECT_BARRIER_ALL = 0x0100,	///<	全部护栏
	OBJECT_BARRIER_UNKNOWN = 0x0101,	///<	其他
	OBJECT_BARRIER_JERSEY = 0x0105,	///<	新泽西护栏
	OBJECT_BARRIER_GUARDRAIL = 0x0108,	///<	安全护栏
	OBJECT_CURB_ALL = 0x0200,	///<	全部路牙
	OBJECT_CURB_NORMAL = 0x0201,	///<	路牙
	OBJECT_MARKING_ALL = 0x0300,	///<	全部记号
	OBJECT_MARKING_TEXT = 0x0301,	///<	文字
	OBJECT_MARKING_ARROW_STRAIGHT = 0x0302,	///<	箭头：直行
	OBJECT_MARKING_ARROW_LEFT = 0x0303,	///<	箭头：左转
	OBJECT_MARKING_ARROW_RIGHT = 0x0304,	///<	箭头：右转
	OBJECT_MARKING_ARROW_STRAIGHT_AND_LEFT = 0x0305,	///<	箭头：左转+直行
	OBJECT_MARKING_ARROW_STRAIGHT_AND_RIGHT = 0x0306,	///<	箭头：右转+直行
	OBJECT_MARKING_ARROW_LEFT_AND_RIGHT = 0x0307,	///<	箭头：左转+右转
	OBJECT_MARKING_STOP_LINE = 0x0309,	///<	停止线
	OBJECT_MARKING_CROSSWALK = 0x030A,	///<	人行横道
	OBJECT_MARKING_SIGN = 0x030B,	///<	地面符号
	OBJECT_MARKING_YIELD_INDICATION = 0x030D,	///<	让行指示
	OBJECT_MARKING_VISUAL_SPEED_BUMP = 0x030E,	///<	减速带
	OBJECT_MARKING_SHADED_AREA = 0x030F,	///<	导流区
	OBJECT_MARKING_OTHER = 0x0310,	///<	其他地面标志类型
	OBJECT_OVERHEAD_STRUCTURE_ALL = 0x0400,	///<	全部上方障碍物面
	OBJECT_OVERHEAD_STRUCTURE_NORMAL = 0x0401,	///<	上方障碍物面
	OBJECT_PERPENDICULAR_WALL_ALL = 0x0500,	///<	全部垂直墙
	OBJECT_PERPENDICULAR_WALL_NORMAL = 0x0501,	///<	垂直墙
	OBJECT_POLE_ALL = 0x0600,	///<	全部杆/柱
	OBJECT_POLE_DELINEATOR_POST = 0x0603,	///<	轮廓标
	OBJECT_POLE_UNCLASSIFIED = 0x0608,	///<	未分类的杆状物
	OBJECT_SIGN_ALL = 0x0700,	///<	全部交通标牌
	OBJECT_SIGN_CURVE_RIGHT = 0x070A,	///<	向右急弯路
	OBJECT_SIGN_CURVE_LEFT = 0x070B,	///<	向左急弯路
	OBJECT_SIGN_NO_OVERTAKING = 0x072F,	///<	禁止超车
	OBJECT_SIGN_NO_OVERTAKING_END = 0x0730,	///<	解除禁止超车
	OBJECT_SIGN_SPEED_LIMIT = 0x0758,	///<	最高限速
	OBJECT_SIGN_SPEED_LIMIT_END = 0x0759,	///<	限速解除
	OBJECT_SIGN_ADVISORY_SPEED_LIMIT = 0x0769,	///<	建议限速
	OBJECT_SIGN_VARIABLE_SPEED_LIMIT = 0x076C,	///<	可变限速
	OBJECT_SIGN_VARIABLE = 0x076D,	///<	可变交通信息（其它）
	OBJECT_SIGN_DO_NOT_ENTER = 0x078C,	///<	禁止驶入
	OBJECT_SIGN_OTHER = 0x07FF,	///<	其它
	OBJECT_TRAFFIC_LIGHT_ALL = 0x0800,	///<	全部信号灯
	OBJECT_TRAFFIC_LIGHT_INTERSECTION_TRAFFIC_FLOW_CONTROL = 0x080C,	///<	路口交通流控制信号灯 
	OBJECT_TRAFFIC_LIGHT_RAMP_CONTROL = 0x080D,	///<	匝道控制信号灯 
};
/**
 * @brief OBJECT_COLOR
 * 
 */
enum OBJECT_COLOR {
	WHITE = 0,	///<	白色
	LIGHT_GRAY = 1,	///<	浅灰色
	GRAY = 2,	///<	灰色
	DARK_GRAY = 3,	///<	深灰色
	BLACK = 4,	///<	黑色
	RED = 5,	///<	红色
	YELLOW = 6,	///<	黄色
	GREEN = 7,	///<	绿色
	CYAN = 8,	///<	青色
	BLUE = 9,	///<	蓝色
	ORANGE = 10,	///<	橙色
	BROWN = 11,	///<	棕色
	COLORFUL = 12,	///<	彩色
	UNKNOWN_COLOR = 15,	///<	其他
};
/**
 * @brief FUZZY_TIME_DOMAIN
 * 
 */
enum FUZZY_TIME_DOMAIN {
	SCHOOL = 3,	///<	对学校周边生效
};
/**
 * @brief BOOL
 * 
 */
enum BOOL {
	True,	///<	True
	False,	///<	False
};
/**
 * @brief ROAD_KIND
 * 
 */
enum ROAD_KIND {
	Motorway = 1,	///<	高速道路
	UrbanMotorway = 2,	///<	城市快速路
	LocalRoad = 3,	///<	一般道路
};
#define	INVALID_MESH_ID	(0)
#define	INVALID_TRANSITION_NO	(-1)
#define	INVALID_LANE_GROUP_ID	(-1)
#define	INVALID_LANE_ID	(-1)


/**
 * @brief MeshId
 * 
 */
class DLL_PUBLIC CMeshId
{
public:
	CMeshId();

	explicit CMeshId(
		  const uint &m_uiMeshId_
		, const ushort &m_usRegion_ = 0
		, const ushort &m_usVersion_ = 0
		);

public:
	/**
	 * @brief 取得MeshId
	 *
	 * @return MeshId
	 */
	const uint& GetMeshId() const;


public:
	uint														m_uiMeshId;									///<	  MeshId  
	ushort														m_usRegion;									///<	  Region  
	ushort														m_usVersion;								///<	  Version  
};


/**
 * @brief NodeId
 * 
 */
class DLL_PUBLIC CNodeId
{
public:
	CNodeId();

	explicit CNodeId(
		  const CMeshId &m_clMeshId_
		, const ushort &m_usNodeId_ = 0
		);

public:
	/**
	 * @brief 取得MeshId
	 *
	 * @return MeshId
	 */
	const CMeshId& GetMeshId() const;


public:
	CMeshId														m_clMeshId;									///<	  MeshId  
	ushort														m_usNodeId;									///<	  NodeId  
};


/**
 * @brief LinkId
 * 
 */
class DLL_PUBLIC CLinkId
{
public:
	CLinkId();

	explicit CLinkId(
		  const CMeshId &m_clMeshId_
		, const ushort &m_usLinkId_ = 0
		);

public:
	/**
	 * @brief 取得MeshId
	 *
	 * @return MeshId
	 */
	const CMeshId& GetMeshId() const;


public:
	CMeshId														m_clMeshId;									///<	  MeshId  
	ushort														m_usLinkId;									///<	  LinkId  
};


/**
 * @brief DirLinkId
 * 
 */
class DLL_PUBLIC CDirLinkId
{
public:
	CDirLinkId();

	explicit CDirLinkId(
		  const CLinkId &m_clLinkId_
		, const uchar &m_ucPos_ = 0
		);

public:
	/**
	 * @brief 取得LinkId
	 *
	 * @return LinkId
	 */
	const CLinkId& GetLinkId() const;

	/**
	 * @brief 取得Pos
	 *
	 * @return Pos
	 */
	LINK_DIRECTION GetPos() const;


public:
	CLinkId														m_clLinkId;									///<	  LinkId  
	uchar														m_ucPos;									///<	  Pos  
};


/**
 * @brief LinkGeoId
 * 
 */
class DLL_PUBLIC CLinkGeoId
{
public:
	CLinkGeoId();

	explicit CLinkGeoId(
		  const CMeshId &m_clMeshId_
		, const ushort &m_usLinkGeoId_ = 0
		);

public:
	/**
	 * @brief 取得MeshId
	 *
	 * @return MeshId
	 */
	const CMeshId& GetMeshId() const;


public:
	CMeshId														m_clMeshId;									///<	  MeshId  
	ushort														m_usLinkGeoId;								///<	  LinkGeoId  
};


/**
 * @brief DirLinkGeoId
 * 
 */
class DLL_PUBLIC CDirLinkGeoId
{
public:
	CDirLinkGeoId();

	explicit CDirLinkGeoId(
		  const CLinkGeoId &m_clLinkGeoId_
		, const uchar &m_ucPos_ = 0
		);

public:
	/**
	 * @brief 取得LinkGeoId
	 *
	 * @return LinkGeoId
	 */
	const CLinkGeoId& GetLinkGeoId() const;

	/**
	 * @brief 取得Pos
	 *
	 * @return Pos
	 */
	LINK_DIRECTION GetPos() const;


public:
	CLinkGeoId													m_clLinkGeoId;								///<	  LinkGeoId  
	uchar														m_ucPos;									///<	  Pos  
};


/**
 * @brief LaneGroupId
 * 
 */
class DLL_PUBLIC CLaneGroupId
{
public:
	CLaneGroupId();

	explicit CLaneGroupId(
		  const CMeshId &m_clMeshId_
		, const uint &m_uiLaneGroupId_ = 0
		);

public:
	/**
	 * @brief 取得MeshId
	 *
	 * @return MeshId
	 */
	const CMeshId& GetMeshId() const;


public:
	CMeshId														m_clMeshId;									///<	  MeshId  
	uint														m_uiLaneGroupId;							///<	  LaneGroupId  
};


/**
 * @brief LaneId
 * 
 */
class DLL_PUBLIC CLaneId
{
public:
	CLaneId();

	explicit CLaneId(
		  const CLaneGroupId &m_clLaneGroupId_
		, const uchar &m_ucLaneNo_ = 0
		);

public:
	/**
	 * @brief 取得LaneGroupId
	 *
	 * @return LaneGroupId
	 */
	const CLaneGroupId& GetLaneGroupId() const;

	/**
	 * @brief 取得LaneNo
	 *
	 * @return 在LaneGroup内的编号，编号从0开始
	 */
	const uchar& GetLaneNo() const;


public:
	CLaneGroupId												m_clLaneGroupId;							///<	  LaneGroupId  
	uchar														m_ucLaneNo;									///<	  在LaneGroup内的编号，编号从0开始  
};


/**
 * @brief LaneBoundaryId
 * 
 */
class DLL_PUBLIC CLaneBoundaryId
{
public:
	CLaneBoundaryId();

	explicit CLaneBoundaryId(
		  const CLaneGroupId &m_clLaneGroupId_
		, const uchar &m_ucLaneBoundaryNo_ = 0
		);

public:
	/**
	 * @brief 取得LaneGroupId
	 *
	 * @return LaneGroupId
	 */
	const CLaneGroupId& GetLaneGroupId() const;

	/**
	 * @brief 取得LaneBoundaryNo
	 *
	 * @return 车道边线的序号，在LaneBoundary中的下标
	 */
	const uchar& GetLaneBoundaryNo() const;


public:
	CLaneGroupId												m_clLaneGroupId;							///<	  LaneGroupId  
	uchar														m_ucLaneBoundaryNo;							///<	  车道边线的序号，在LaneBoundary中的下标  
};


/**
 * @brief ObjectShortId
 * 
 */
class DLL_PUBLIC CObjectShortId
{
public:
	CObjectShortId();

	explicit CObjectShortId(
		  const uint &m_uiId_
		, const uchar &m_ucSubVersion_ = 0
		);

public:
	/**
	 * @brief 取得Id
	 *
	 * @return Id
	 */
	const uint& GetId() const;

	/**
	 * @brief 取得SubVersion
	 *
	 * @return SubVersion
	 */
	const uchar& GetSubVersion() const;


public:
	uint														m_uiId;										///<	  Id  
	uchar														m_ucSubVersion;								///<	  SubVersion  
};


/**
 * @brief ObjectId
 * 
 */
class DLL_PUBLIC CObjectId
{
public:
	CObjectId();

	explicit CObjectId(
		  const CMeshId &m_clMeshId_
		, const CObjectShortId &m_clObjectId_ = CObjectShortId()
		, const ushort &m_usObjectType_ = 0
		);

public:
	/**
	 * @brief 取得MeshId
	 *
	 * @return MeshId
	 */
	const CMeshId& GetMeshId() const;

	/**
	 * @brief 取得ObjectType
	 *
	 * @return ObjectType
	 */
	OBJECT_TYPE GetObjectType() const;


public:
	CMeshId														m_clMeshId;									///<	  MeshId  
	CObjectShortId												m_clObjectId;								///<	  ObjectId  
	ushort														m_usObjectType;								///<	  ObjectType  
};


/**
 * @brief ObjectGroupShortId
 * 
 */
class DLL_PUBLIC CObjectGroupShortId
{
public:
	CObjectGroupShortId();

	explicit CObjectGroupShortId(
		  const uint &m_uiId_
		, const uchar &m_ucSubVersion_ = 0
		);

public:
	/**
	 * @brief 取得Id
	 *
	 * @return Id
	 */
	const uint& GetId() const;

	/**
	 * @brief 取得SubVersion
	 *
	 * @return SubVersion
	 */
	const uchar& GetSubVersion() const;


public:
	uint														m_uiId;										///<	  Id  
	uchar														m_ucSubVersion;								///<	  SubVersion  
};


/**
 * @brief ObjectGroupId
 * 
 */
class DLL_PUBLIC CObjectGroupId
{
public:
	CObjectGroupId();

	explicit CObjectGroupId(
		  const CMeshId &m_clMeshId_
		, const CObjectGroupShortId &m_clObjectGroupId_ = CObjectGroupShortId()
		);

public:
	/**
	 * @brief 取得MeshId
	 *
	 * @return MeshId
	 */
	const CMeshId& GetMeshId() const;


public:
	CMeshId														m_clMeshId;									///<	  MeshId  
	CObjectGroupShortId											m_clObjectGroupId;							///<	  ObjectGroupId  
};


/**
 * @brief ObstacleShortId
 * 
 */
class DLL_PUBLIC CObstacleShortId
{
public:
	CObstacleShortId();

	explicit CObstacleShortId(
		  const uint &m_uiId_
		, const uchar &m_ucSubVersion_ = 0
		);

public:
	/**
	 * @brief 取得Id
	 *
	 * @return Id
	 */
	const uint& GetId() const;

	/**
	 * @brief 取得SubVersion
	 *
	 * @return SubVersion
	 */
	const uchar& GetSubVersion() const;


public:
	uint														m_uiId;										///<	  Id  
	uchar														m_ucSubVersion;								///<	  SubVersion  
};


/**
 * @brief ObstacleId
 * 
 */
class DLL_PUBLIC CObstacleId
{
public:
	CObstacleId();

	explicit CObstacleId(
		  const CMeshId &m_clMeshId_
		, const CObstacleShortId &m_clObstacleId_ = CObstacleShortId()
		);

public:
	/**
	 * @brief 取得MeshId
	 *
	 * @return MeshId
	 */
	const CMeshId& GetMeshId() const;


public:
	CMeshId														m_clMeshId;									///<	  MeshId  
	CObstacleShortId											m_clObstacleId;								///<	  ObstacleId  
};


/**
 * @brief IntersectionAreaId
 * 
 */
class DLL_PUBLIC CIntersectionAreaId
{
public:
	CIntersectionAreaId();

	explicit CIntersectionAreaId(
		  const CMeshId &m_clMeshId_
		, const ushort &m_usIntersectionAreaId_ = 0
		);

public:
	/**
	 * @brief 取得MeshId
	 *
	 * @return MeshId
	 */
	const CMeshId& GetMeshId() const;


public:
	CMeshId														m_clMeshId;									///<	  MeshId  
	ushort														m_usIntersectionAreaId;						///<	  IntersectionAreaId  
};


/**
 * @brief Link共通属性
 * 
 */
class DLL_PUBLIC CLinkCommonAttribute
{
public:
	CLinkCommonAttribute();

	explicit CLinkCommonAttribute(
		ushort v_ 
		);

public:
	/**
	 * @brief 取得PluralJunction
	 * @details 
	 *
	 * @return 如果link是复杂交叉口内的link，则设置为true
	 */
	BOOL GetPluralJunction() const;

	/**
	 * @brief 取得Urban
	 * @details 
	 *
	 * @return 如果Link位于市区内，则设置为true
	 */
	BOOL GetUrban() const;

	/**
	 * @brief 取得ServiceArea
	 * @details 
	 *
	 * @return link是服务区的入口、部分或出口。如果一条link通向高速公路休息区、停车场或高尔夫球场，则必须标记为服务区
	 */
	BOOL GetServiceArea() const;

	/**
	 * @brief 取得ControlledAccess
	 * @details 
	 *
	 * @return link是否是限制通行道路，如高速公路
	 */
	BOOL GetControlledAccess() const;

	/**
	 * @brief 取得Bridge
	 * @details 
	 *
	 * @return 如果Link至少部分是桥，则设置为true 
	 */
	BOOL GetBridge() const;

	/**
	 * @brief 取得Tunnel
	 * @details 
	 *
	 * @return 如果Link至少部分是隧道，则设置为true 
	 */
	BOOL GetTunnel() const;

	/**
	 * @brief 取得TravelDirection
	 * @details 
	 *
	 * @return 通行方向，包括正方向通行、反方向通行，双方向通行
	 */
	TRAVEL_DIRECTION GetTravelDirection() const;

	/**
	 * @brief 取得LinkType
	 * @details 
	 *
	 * @return 道路类型，包括普通道路、匝道、环岛
	 */
	LINK_TYPE GetLinkType() const;

	/**
	 * @brief 取得RoadKind
	 * @details 
	 *
	 * @return 道路类型
	 */
	ROAD_KIND GetRoadKind() const;


public:
	union {
		ushort													v;
		struct {
			ushort												m_ucPluralJunction			: 1;			///<	  如果link是复杂交叉口内的link，则设置为true  
			ushort												m_ucUrban					: 1;			///<	  如果Link位于市区内，则设置为true  
			ushort												m_ucServiceArea				: 1;			///<	  link是服务区的入口、部分或出口。如果一条link通向高速公路休息区、停车场或高尔夫球场，则必须标记为服务区  
			ushort												m_ucControlledAccess		: 1;			///<	  link是否是限制通行道路，如高速公路  
			ushort												m_ucBridge					: 1;			///<	  如果Link至少部分是桥，则设置为true   
			ushort												m_ucTunnel					: 1;			///<	  如果Link至少部分是隧道，则设置为true   
			ushort												m_ucTravelDirection			: 2;			///<	  通行方向，包括正方向通行、反方向通行，双方向通行  
			ushort												m_ucLinkType				: 4;			///<	  道路类型，包括普通道路、匝道、环岛  
			ushort												m_ucRoadKind				: 4;			///<	  道路类型  
		};
	};
};

}
}

PRAGMA_PACK_POP

#endif	//	__NISCOMMONSTRUCT_H_
